package com.sbp.message.proxy;

import com.alibaba.fastjson.JSON;
import com.dap.api.ISunriseService;
import com.dap.param.ControlData;
import com.dap.param.StringInput;
import com.dap.utils.SpringUtils;
import com.sbp.message.api.entity.Message;
import com.sbp.message.api.entity.MessageType;
import com.sbp.message.conf.ActiveMQConfig;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;

public class ConsumerServicesManager implements InitializingBean {
    private static final Logger logger = LoggerFactory.getLogger(ConsumerServicesManager.class);

    private ActiveMQConfig activeMQConfig;
    public void setActiveMQConfig(ActiveMQConfig activeMQConfig) {
        this.activeMQConfig = activeMQConfig;
    }



    public static class SunriseServiceAndParam {
        public final ISunriseService service;
        public final StringInput stringInput;
        public SunriseServiceAndParam(ISunriseService service, StringInput stringInput) {
            this.service = service;
            this.stringInput = stringInput;
        }
    }
    public SunriseServiceAndParam resolveSunriseServiceAndParam(Message message) {
        String dubboGroupName;
        if (message.getMessageType() == MessageType.MESSAGE_QUEUE.getValue()) {
            dubboGroupName = message.getDestination();
        } else {
            dubboGroupName = activeMQConfig.getAppName() + "." + message.getDestination();
        }

        ControlData controlData = new ControlData();
        controlData.setInternalRequestSource("message");
        StringInput stringInput = new StringInput(controlData, message.getContent());

        ISunriseService service = localConsumerServiceMap.get(dubboGroupName);
        if (null == service) {
            logger.warn("message has no service, dubboGroupName={}, message=\n{}", dubboGroupName, JSON.toJSONString(message));
            return null;
        }

        return new SunriseServiceAndParam(service, stringInput);
    }


    private Map<String, ISunriseService> localConsumerServiceMap = new HashMap<>();
    private static ArrayList<String> generateListFromStr(String str) {
        ArrayList<String> list = new ArrayList<>();

        String[] arr = str.split(",");
        for (String element : arr) {
            element = element.trim();
            if (!StringUtils.isEmpty(element)) {
                list.add(element);
            }
        }

        return list;
    }
    private void initLocalConsumerServiceMap(String groupNamePrefix, String destinationsStr, String serviceNamesStr) {
        ArrayList<String> groupNameList = generateListFromStr(destinationsStr);
        ArrayList<String> serviceNameList = generateListFromStr(serviceNamesStr);

        final int minLen = Math.min(groupNameList.size(), serviceNameList.size());
        for (int i=0; i<minLen; ++i) {
            String groupName = groupNameList.get(i);
            if (null != groupNamePrefix)
                groupName = groupNamePrefix + groupName;

            String serviceName = serviceNameList.get(i);
            ISunriseService service = SpringUtils.getBean(serviceName);
            if (null != service) {
                localConsumerServiceMap.put(groupName, service);
            } else {
                logger.warn("no service named {}, groupName is {}", serviceName, groupName);
            }
        }
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        if (!StringUtils.isEmpty(activeMQConfig.getAmqQueueServiceName())) {
            initLocalConsumerServiceMap(null,
                    activeMQConfig.getAmqQueueDestination(),
                    activeMQConfig.getAmqQueueServiceName());
        }

        if (!StringUtils.isEmpty(activeMQConfig.getAmqTopicServiceName())) {
            initLocalConsumerServiceMap(activeMQConfig.getAppName() + ".VirtualTopic.",
                    activeMQConfig.getAmqTopicDestinationSuffix(),
                    activeMQConfig.getAmqTopicServiceName());
        }

        logger.info("localConsumerServiceMap={}", JSON.toJSONString(localConsumerServiceMap));
    }
}
